package com.bajiao.third.utils;

import com.aliyun.oss.*;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PolicyConditions;
import com.bajiao.common.constant.CommonConstant;
import com.bajiao.common.exception.DataHandleException;
import com.bajiao.common.util.DateUtils;
import com.bajiao.common.util.IDGeneratorUtils;
import com.bajiao.common.util.ImageZipUtil;
import com.bajiao.service.config.ConfigService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @author: FanJq
 * @date: 2024-10-10 10:51
 * @description: OSS文件系统实现
 */
@Slf4j
@Component
public class OSSClientUtils {

    private static ConfigService configServiceMove;

    @Autowired
    public void setConfigServiceMove(ConfigService configServiceMove) {
        OSSClientUtils.configServiceMove = configServiceMove;
    }

    /**
     * @Description
     * file对象多图片上传
     * @date 2024/12/11 16:39
     * @author FanJq
     * @param files
     * @return {@link String}
    */
    public static String multipleFileUploadNew(MultipartFile[] files) {

        String urlList = "";
        int sum = 1;
        String nowDate = DateUtils.yyyyMMdd.get().format(new Date());
        if (files != null && files.length > 0) {
            for (MultipartFile picFile : files) {
                String filename = picFile.getOriginalFilename();
                //图片压缩
                ByteArrayInputStream byteArrayInputStream = ImageZipUtil.zipImageFile(picFile, 0.8f, filename);
                //获取输出流
                String uploadFile = uploadFile(byteArrayInputStream, nowDate + "/" + System.currentTimeMillis() + filename.substring(filename.lastIndexOf(".")));
                if (sum != files.length) {
                    urlList += uploadFile + ",";
                } else {
                    urlList += uploadFile;
                }
                sum++;
            }
        }

        return urlList;
    }

    public static Map<String, String> getSignData() {
        try {
            //获取oss客户点实例和对应的参数
            Map<String, Object> ossClientAndParams = getOSSClientAndParams();
            OSS ossClient = (OSS) ossClientAndParams.get("ossClient");
            Map<String, String> params = (Map<String, String>) ossClientAndParams.get("params");
            long expireTime = 60 * 60;//1小时的过期时间
            long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
            Date expiration = new Date(expireEndTime);
            PolicyConditions policyConds = new PolicyConditions();
            // PostObject请求最大可支持的文件大小为5 GB，即CONTENT_LENGTH_RANGE为5*1024*1024*1024
            policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 2 * 1024 * 1024 * 1024L);
            String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
            byte[] binaryData = postPolicy.getBytes("utf-8");
            String encodedPolicy = BinaryUtil.toBase64String(binaryData);
            String postSignature = ossClient.calculatePostSignature(postPolicy);

            Map<String, String> respMap = new LinkedHashMap();
            respMap.put("accessid", params.get("accessKeyId"));
            respMap.put("policy", encodedPolicy);
            respMap.put("signature", postSignature);
            respMap.put("host", params.get("resultUrl"));
            respMap.put("fileName", DateUtils.date2Str(DateUtils.yyyy_mm_dd.get())+"/"+IDGeneratorUtils.getLongId());
            respMap.put("expire", String.valueOf(expireEndTime / 1000));
            return respMap;
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace();
        }
        return null;
    }

    public static Map getOSSClientAndParams() {
        Map<String, Object> result = new HashMap<>();
        Map<String, String> params = new HashMap<>();

        String url = "";
        String accessKeyId = "";
        String accessKeySecret = "";
        String bucketName = "";
        String resultUrl = "";

        //判断配置参数是否正常获取
        Map map = configServiceMove.queryNameAndValueByGroup(CommonConstant.OSS_CONFIG_GROUP);
        if (map.size() == 5) {
            url = (String) map.get("url");
            accessKeyId = (String) map.get("accessKeyId");
            accessKeySecret = (String) map.get("accessKeySecret");
            bucketName = (String) map.get("bucketName");
            resultUrl = (String) map.get("resultUrl");

            params.put("url", url);
            params.put("accessKeyId", accessKeyId);
            params.put("accessKeySecret", accessKeySecret);
            params.put("bucketName", bucketName);
            params.put("resultUrl", resultUrl);
        } else {
            throw new DataHandleException("配置信息错误", 0);
        }


        OSS ossClient = new OSSClientBuilder().build(url, accessKeyId, accessKeySecret);
        result.put("ossClient", ossClient);
        result.put("params", params);
        return result;
    }

    /**
     * @Description
     * 上传流文件
     * @date 2024/12/11 16:41
     * @author FanJq
     * @param in
     * @param fileName
     * @return {@link String}
    */
    public static String uploadFile(InputStream in, String fileName) {
        //获取oss客户点实例和对应的参数
        Map<String, Object> ossClientAndParams = getOSSClientAndParams();
        String bucketName = ((Map<String, String>) ossClientAndParams.get("params")).get("bucketName");

        String suffix = fileName.substring(fileName.lastIndexOf("."));
        fileName = IDGeneratorUtils.getLongId() + suffix;
        String fileKey =  DateUtils.yyyy_mm_dd.get().format(DateUtils.getDate()) + "/" + fileName;

        OSS ossClient = (OSS) ossClientAndParams.get("ossClient");
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentType(getcontentType(suffix));
        ossClient.putObject(bucketName, fileKey, in, objectMetadata);
        ossClient.shutdown();
        return fileKey;
    }

    /**
     * @Description
     * 判断OSS同bucketName下文件是否已存在
     * @date 2024/12/11 16:41
     * @author FanJq
     * @param bucketName
     * @param objectName
     * @return {@link boolean}
    */
    public static boolean checkExist(String bucketName, String objectName) {
        String url = "";
        String accessKeyId = "";
        String accessKeySecret = "";
        //判断配置参数是否正常获取
        Map map = configServiceMove.queryNameAndValueByGroup(CommonConstant.OSS_CONFIG_GROUP);
        if (map.size() == 5) {
            url = (String) map.get("url");
            accessKeyId = (String) map.get("accessKeyId");
            accessKeySecret = (String) map.get("accessKeySecret");
        }
        OSSClient ossClient = new OSSClient(url, accessKeyId,
                accessKeySecret);
        return ossClient.doesObjectExist(bucketName, objectName);
    }

    public static String getcontentType(String FilenameExtension) {
        if (FilenameExtension.equalsIgnoreCase(".bmp")) {
            return "image/bmp";
        }
        if (FilenameExtension.equalsIgnoreCase(".gif")) {
            return "image/gif";
        }
        if (FilenameExtension.equalsIgnoreCase(".jpeg") ||
                FilenameExtension.equalsIgnoreCase(".jpg") ||
                FilenameExtension.equalsIgnoreCase(".png")) {
            return "image/jpg";
        }
        if (FilenameExtension.equalsIgnoreCase(".html")) {
            return "text/html";
        }
        if (FilenameExtension.equalsIgnoreCase(".txt")) {
            return "text/plain";
        }
        if (FilenameExtension.equalsIgnoreCase(".vsd")) {
            return "application/vnd.visio";
        }
        if (FilenameExtension.equalsIgnoreCase(".pptx") ||
                FilenameExtension.equalsIgnoreCase(".ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (FilenameExtension.equalsIgnoreCase(".docx") ||
                FilenameExtension.equalsIgnoreCase(".doc")) {
            return "application/msword";
        }
        if (FilenameExtension.equalsIgnoreCase(".xml")) {
            return "text/xml";
        }
        return "image/jpg";
    }
}
